#!/usr/local/bin/python
# coding: utf-8
import subprocess
import sys
import os
import config
import smtplib
from email.mime.text import MIMEText
import datetime

HBASE_HOME = config.hbase_home
DFS_USED_THRESHOLD = config.dfs_used_threshold

def get_report():
    keys = {'Present Capacity':['Summary',0], 'Name':['DataNode',1]}
    subkv = {}
    report = {}
    key = ''
    cmd=HBASE_HOME+'bin/hadoop dfsadmin -report'
    pidp = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
    text = pidp.stdout.readlines()
    if (len(text) > 0):
        for line in text:
            line = line.strip('\n')
            if (len(line) == 0):
                continue
            kvalue = line.split(':') 
            if (len(kvalue) < 2):
                continue
            kvalue[0] = kvalue[0].strip()
            kvalue[1] = kvalue[1].strip()

            if (kvalue[0] in keys.keys()):
                if (len(key) != 0):
                    report[key] = subkv
                    subkv = {}
                if (keys[kvalue[0]][1] > 0):
                    key = '%s%d' % (keys[kvalue[0]][0], keys[kvalue[0]][1])
                    keys[kvalue[0]][1] += 1
                else:
                    key = keys[kvalue[0]][0]
            subkv[kvalue[0]] = kvalue[1]
        report[key] = subkv

    return report

def sendmail(subject, content):
    '''
    subject:主题
    content:内容
    '''
    me = config.mailfrom
    
    msg = MIMEText(content, 'html', 'utf-8')
    msg['Subject'] = subject
    msg['From'] = me
    msg['To'] = ";".join(config.mailto)
        
    try:
        s = smtplib.SMTP()
        s.connect(config.mailserver)
        s.login(config.mailfrom, config.mailpasswd)
        s.sendmail(me, config.mailto, msg.as_string())
        s.close()
        return True
    except Exception, e:
        print str(e)
        return False

def print_summary(report):
    text = '<table border=1><tr><td><font size=5>Hadoop Parameter</font></td><td><font size=5>Value</font></td></tr>%s</table>'
    warning = '<font color="red">%s</font>'
    row = '<tr><td>%s</td><td>%s</td></tr>'
    ret = ''
    summary = report['Summary']
    warnings = False
    for key in summary.keys():
        if (key == 'Datanodes available'):
            tmp = summary[key].split('(')
            avtive_num = int(tmp[0].strip())
            total_num = int(tmp[1].split()[0].strip())
            if (avtive_num != total_num):
                print 'Warning: (%d) DataNode Fail' % (total_num - avtive_num)
                ret +=  row % (warning % (key), warning % (summary[key]))
                warnings = True
            else:
                ret += row % (key, summary[key])
        elif (key == 'Configured Capacity'):
            ret += row % (key, summary[key].split('(')[1].split(')')[0])
        elif (key == 'Present Capacity'):
            ret += row % (key, summary[key].split('(')[1].split(')')[0])
        elif (key == 'DFS Used'):
            ret += row % (key, summary[key].split('(')[1].split(')')[0])
        elif (key == 'DFS Used%'):
            ratio = float(summary[key].split('%')[0])
            if (ratio > DFS_USED_THRESHOLD):
                print 'Warning: DFS Used(%f) Exceed Threshold(%f%%)' % (ratio, DFS_USED_THRESHOLD)
                ret += row % (warning % (key), warning % (summary[key]))
                warnings = True
            else:
                ret += row % (key, summary[key])
        elif (key == 'Under replicated blocks'):
            ret += row % (key, summary[key])
        elif (key == 'Blocks with corrupt replicas'):
            blocks = int(summary[key])
            if (blocks > 0):
                ret += row % (warning % (key), warning % (summary[key]))
                warnings = True
            else:
                ret += row % (key, summary[key])
        elif (key == 'Missing blocks'):
            blocks = int(summary[key])
            if (blocks > 0):
                ret += row % (warning % (key), warning % (summary[key]))
                warnings = True
            else:
                ret += row % (key, summary[key])

    return (warnings, text % (ret))

def print_datanode(text):
    row = '<tr><td>%s</td><td>%s</td><td>%s</td></tr>'
    ret = ''
    warning = '<font color="red">%s</font>'
    warnings = False
    datanode = text['Name']
    key = 'Configured Capacity'
    capacity = int(text[key].split()[0])
    if (capacity <= 0):
        print 'DataNode (%s) Fault' % (datanode)
        warnings = True
        return (warnings, '<tr><td>%s</td><td col=2>%s</td></tr>' % (warning % (datanode), warning % ('Fault')))
    else:
        ret += row % (datanode, key, text[key].split('(')[1].split(')')[0])

    for key in text.keys():
        if (key == 'DFS Used%'):
            ratio = float(text[key].split('%')[0])
            if (ratio > DFS_USED_THRESHOLD):
                print 'Warning: DataNode (%s) DFS Used(%f) Exceed Threshold(%f%%)' % (text['Name'], ratio, DFS_USED_THRESHOLD)
                ret += row % (datanode, warning % (key), warning % (text[key]))
                warnings = True
            else:
                ret += row % (datanode, key, text[key])
        elif (key == 'DFS Remaining'):
            ret += row % (datanode, key, text[key].split('(')[1].split(')')[0])
        elif (key == 'DFS Used'):
            ret += row % (datanode, key, text[key].split('(')[1].split(')')[0])
        elif (key == 'Non DFS Used'):
            ret += row % (datanode, key, text[key].split('(')[1].split(')')[0])
        
        datanode = ''

    return (warnings, ret)

def print_datanodes(report):
    text = '<table border=1><tr><td><font size=5>DataNode</font></td><td><font size=5>Parameter</font></td><td><font size=5>Value</font></td></tr>%s</table>'
    rows = ''
    ret = ''
    warnings = ''
    for key in report.keys():
        if (key[:8] == 'DataNode'):
            (a, ret) = print_datanode(report[key])
            rows += ret
            if a:
                warnings = True
    return (warnings, text % (rows))
 
def print_report(report):
    h = '<h2>DataPlatform Hadoop Information</h2><br/>'
    text = ''
    warnings = False
    ret = ''

    (a, ret) = print_summary(report)
    if a:
        warnings = True
    text += ret

    text += '<br/>'

    (a, ret) = print_datanodes(report)
    if a:
        warnings = True
    text += ret

    if warnings:
        sendmail("DataPlatform Report", h + text)
    else:
        now = datetime.datetime.now()
        print now.strftime('%Y-%m-%d %H:%M:%S') + ' everything is ok'

def print_error():
    h = '<h2>DataPlatform Hadoop Information</h2><br/>'
    h += '<h3><font color="red">DataPlatform Hadoop Fault</font></h3>'
    sendmail("DataPlatform Report", h)

if __name__ == '__main__':
    report = get_report()
    if (report):
        print_report(report)
    else:
        print_error()
